﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using iTextSharp.text.pdf;
using iTextSharp.text;
using System.IO;
using System.Collections;

namespace PDFMerge
{
    /// <summary>
    /// Static class used to merge SimplePDFDoc into a final PDF doc
    /// </summary>
    static class PDFMerger
    {
       /// <summary>
       /// Main Method used to merge a list of SimplePDFDocs into one PDF
       /// </summary>
       /// <param name="pdfList">List of SimplePDFDocs to merge (in order)</param>
       /// <param name="savePath">An output file path for the merged document</param>
        public static void PerformMerge(List<SimplePDFDoc> pdfList, string savePath)
        {
            string outFile = string.Empty;
            int pageOffset = 0;
            ArrayList master = new ArrayList();
            int f = 0;
            Document document = null;
            PdfCopy writer = null;

            while (f < pdfList.Count)
            {
                //create a reader for a certain document
                PdfReader reader = new PdfReader(pdfList[f].FilePath);
                reader.ConsolidateNamedDestinations();

                //Get total number of pages
                int n = reader.NumberOfPages;
                pageOffset += n;

                if (f == 0)
                {
                    //step 1 create the document
                    document = new Document(reader.GetPageSizeWithRotation(1));

                    // step 2: we create a writer that listens to the document
                    writer = new PdfCopy(document, new FileStream(savePath, FileMode.Create));

                    // step 3: we open the document
                    document.Open();
                }
                // step 4: we add content
                for (int i = 0; i < n; )
                {
                    ++i;
                    if (writer != null)
                    {
                        PdfImportedPage page = writer.GetImportedPage(reader, i);
                        writer.AddPage(page);
                    }
                }
                PRAcroForm form = reader.AcroForm;
                if (form != null && writer != null)
                {
                    writer.CopyAcroForm(reader);
                }
                f++;
            }
            // step 5: we close the document
            if (document != null)
            {
                document.Close();              
            }
        }

        #region Credit goes to http://www.codeproject.com/Articles/28283/Simple-NET-PDF-Merger for providing this solution
        #endregion
        internal class PdfPageEvents : IPdfPageEvent
        {
            #region members
            private BaseFont _baseFont = null;
            private PdfContentByte _content;
            #endregion

            #region IPdfPageEvent Members
            public void OnOpenDocument(PdfWriter writer, Document document)
            {
                _baseFont = BaseFont.CreateFont(BaseFont.HELVETICA,
                                 BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
                _content = writer.DirectContent;
            }

            public void OnStartPage(PdfWriter writer, Document document)
            { }

            public void OnEndPage(PdfWriter writer, Document document)
            {
                // Write header text
                string headerText = "PDF Merger by Smart-Soft";
                _content.BeginText();
                _content.SetFontAndSize(_baseFont, 8);
                _content.SetTextMatrix(GetCenterTextPosition(headerText,
                                       writer), writer.PageSize.Height - 10);
                _content.ShowText(headerText);
                _content.EndText();

                // Write footer text (page numbers)
                string text = "Page " + writer.PageNumber;
                _content.BeginText();
                _content.SetFontAndSize(_baseFont, 8);
                _content.SetTextMatrix(GetCenterTextPosition(text, writer), 10);
                _content.ShowText(text);
                _content.EndText();
            }

            public void OnCloseDocument(PdfWriter writer, Document document)
            { }

            public void OnParagraph(PdfWriter writer,
                        Document document, float paragraphPosition)
            { }

            public void OnParagraphEnd(PdfWriter writer,
                        Document document, float paragraphPosition)
            { }

            public void OnChapter(PdfWriter writer, Document document,
                                  float paragraphPosition, Paragraph title)
            { }

            public void OnChapterEnd(PdfWriter writer,
                        Document document, float paragraphPosition)
            { }

            public void OnSection(PdfWriter writer, Document document,
                        float paragraphPosition, int depth, Paragraph title)
            { }

            public void OnSectionEnd(PdfWriter writer,
                        Document document, float paragraphPosition)
            { }

            public void OnGenericTag(PdfWriter writer, Document document,
                                     Rectangle rect, string text)
            { }
            #endregion

            private float GetCenterTextPosition(string text, PdfWriter writer)
            {
                return writer.PageSize.Width / 2 - _baseFont.GetWidthPoint(text, 8) / 2;
            }
        }
    }
}
